package com.hhs.storage.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.AbstractWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hhs.storage.bean.*;
import com.hhs.storage.dao.FlowDao;
import com.hhs.storage.service.BaseDepartmentService;
import com.hhs.storage.service.BaseRoleService;
import com.hhs.storage.service.ContractService;
import com.hhs.storage.service.FlowService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hhs.storage.util.SysUtil;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hhs
 * @since 2022-12-01
 */
@Service
@Lazy
@Transactional
public class FlowServiceImpl extends ServiceImpl<FlowDao, Flow> implements FlowService {

    @Resource
    ContractService contractService;
    @Resource
    BaseRoleService roleService;
    @Resource
    HttpServletRequest request;
    @Resource
    BaseDepartmentService departmentService;
//    @Override
//    public void create(Integer type, Integer status, String mainId, String creater, String remark) {
//        //生成流程对象
//        Flow flow = new Flow();
//        flow.setMainId(mainId);
//        flow.setType(type);
//        flow.setCreater(creater);
//        flow.setStatus(status);
//        flow.setCreateTime(LocalDateTime.now().plusSeconds(1));
//        flow.setRemark(remark);
//        //若是最后流程结束，同时设置endtime
//        if(type==Flow.TYPE_CONTRACT &&
//                (status==Contract.STATUS_FINISHED )){
//            flow.setEndTime(LocalDateTime.now().plusSeconds(1));
//        }
//        this.save(flow);
//    }

    @Override
    public void create(Integer type, Integer status, Integer statusJunior, String mainId, String creater, String remark) {
        //生成流程对象
        Flow flow = new Flow();
        flow.setMainId(mainId);
        flow.setType(type);
        flow.setCreater(creater);
        flow.setStatus(status);
        flow.setStatusJunior(statusJunior);
        flow.setCreateTime(LocalDateTime.now().plusSeconds(1));
        flow.setRemark(remark);
        //若是最后流程结束，同时设置endtime
        if(status==Contract.STATUS_FINISHED ){
            flow.setEndTime(LocalDateTime.now().plusSeconds(1));
        }
        this.save(flow);
    }

    @Override
    public void createWithJsonData(Integer type, Integer status, Integer statusJunior, String mainId, String creater, String remark, String jsonData) {
        //生成流程对象
        Flow flow = new Flow();
        flow.setMainId(mainId);
        flow.setType(type);
        flow.setCreater(creater);
        flow.setStatus(status);
        flow.setStatusJunior(statusJunior);
        flow.setCreateTime(LocalDateTime.now().plusSeconds(1));
        flow.setRemark(remark);
        //设置要修改的数据，等审核通过后，才更新到表里
        flow.setJsonData(jsonData);
        //若是最后流程结束，同时设置endtime
        if(status==Contract.STATUS_FINISHED){
            flow.setEndTime(LocalDateTime.now().plusSeconds(1));
        }
        this.save(flow);
    }

    @Override
    public void createWithEndTime(Integer type, Integer status, String mainId, String creater, String remark) {
        //生成流程对象
        Flow flow = new Flow();
        flow.setMainId(mainId);
        flow.setType(type);
        flow.setCreater(creater);
        flow.setStatus(status);
        flow.setCreateTime(LocalDateTime.now());
        flow.setRemark(remark);
        flow.setEndTime(LocalDateTime.now());
        this.save(flow);
    }

    @Override
    public Map dele(String id) {
        if (!StringUtils.isEmpty(id)) {
        }
        return ResponseInfo.success();
    }

    @Override
    public Map deleByMainId(String id) {
        if (!StringUtils.isEmpty(id)) {
            QueryWrapper ew = new QueryWrapper<Flow>();
            ew.eq("main_id", id);
            this.remove(ew);
        }

        return ResponseInfo.success();
    }

    @Override
    public  Map<String, Object> getAll(InputParam inputParam) {
        QueryWrapper ew = new QueryWrapper<Flow>();
        if(inputParam.getQueryType()!=null) {
                //初审1，
                if(1==inputParam.getQueryType()){
//                    //来自初审界面发起的查询请求，需要查询 状态值为 2和5
//                    // 合同延期也需要走流程，初审加入 状态值8 和 11
//                    ew=new QueryWrapper<Flow>().and(i -> i.eq("status", 2)
//                            .or().eq("status", 5)
//                            .or().eq("status", 8)
//                            .or().eq("status", 11));
                    //初审 状态2
                    ew.eq("status", 2);
                }
                //终审2，状态值为4
                //合同延期也需要走流程，终审加入 状态值10
                if(2==inputParam.getQueryType()){
                    //来自终审界面发起的查询请求
//                    ew=new QueryWrapper<Flow>().and(i -> i.eq("status", 4)
//                            .or().eq("status", 10));
                    ////终审，状态值为4
                    ew.eq("status", 4);
                }
            }
        if(!StringUtils.isEmpty(inputParam.getMainId())) {
            //主单据来源id
            ew.eq("main_id", inputParam.getMainId());
        }
        if(inputParam.getIsFinished()!=null && inputParam.getIsFinished()) {
            //流程结束时间，true，表示流程已结束
            ew.isNotNull("end_time");
        }
        if(inputParam.getIsFinished()!=null && !inputParam.getIsFinished()) {
            //false表示在途单，默认
            ew.isNull("end_time");
        }
        ew.orderByDesc("create_time");
        /**
         * 根据当前登录用户身份查询数据
         */
        String userId=SysUtil.getLoginUserId(request);

        if(roleService.hasRole(SysUtil.ROLE_FLAG_JL,userId )){//当前用户是经理
            //查询经理负责部门下所有部门下属负责的合同
            List<BaseUser> userList=departmentService.getUserDepartAllUser(userId);
            List<String> idList = new ArrayList<>();
            for (int i = 0; i < userList.size(); i++) {
                idList.add("'" + userList.get(i).getId() + "'");
            }
            String userIds = idList.stream().map(String::valueOf).collect(Collectors.joining(","));
            ew.inSql("main_id","SELECT id FROM contract WHERE principal in ("+userIds+")");
        }else if(roleService.hasRole(SysUtil.ROLE_FLAG_YWY,userId )){//当前用户是ywy
            //查询合同是当前业务员负责的
            ew.inSql("main_id","SELECT id FROM contract WHERE principal='"+userId+"'");
        }
        Page<Flow> result = this.page(new Page(
                inputParam.getPage(),
                inputParam.getSize()),ew);
        for (Flow temp : result.getRecords()) {
            String tempMainId = temp.getMainId();
            //合同或者合同延期
            if (temp.getType().equals( Flow.TYPE_CONTRACT) ||
                    temp.getType().equals(Flow.TYPE_CONTRACT_DEFER)||
                    temp.getType().equals(Flow.TYPE_CONTRACT_TEMP)) {
                Contract contract = contractService.getById(tempMainId);
                //获取该合同的所有流程
//                    InputParam tempinp = new InputParam();
//                    temp.setMainId(contract.getId());
//                    List<Flow> flowList = getListAndCreater(tempinp);
//                    contract.setFlowList(flowList);
                //
                temp.setContract(contract);
            }
        }
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("rows", result.getRecords());
        map.put("total",result.getTotal());
        map.put("code", 1);
        return map;
    }

    @Override
    public List<Flow> getListAndCreater(InputParam inputParam) {
        //界面  合同管理——我的录入用
        return this.baseMapper.getListAndCreater(inputParam);
    }

    @Override
    public Flow getCurrent(String mainId) {
        if(StringUtils.isEmpty(mainId)) {
           return null;
        }
        QueryWrapper ew = new QueryWrapper<Flow>();
        ew.eq("main_id", mainId);
        ew.isNull("end_time");
        List<Flow> list = this.list(ew);
        if(list.size()>0){
            return list.get(0);
        }
        return null;
    }

    @Override
    public Map flowOpera(InputParam inputParam) {
        if(inputParam.getFlowNextStatus() ==null ||
            inputParam.getFlowId()==null||
           StringUtils.isEmpty(inputParam.getCurUserId())){
            return ResponseInfo.error("参数错误");
        }
        //查出当前流程
        Flow curFlow = this.getById(inputParam.getFlowId());
        if(curFlow.getEndTime()!=null){
            return ResponseInfo.error("流程错误");
        }
        curFlow.setEndTime(LocalDateTime.now());
        //更新当前流程结束时间
        this.updateById(curFlow);
        //生成下一步流程
        this.create(curFlow.getType(),
                inputParam.getFlowNextStatus(),
                inputParam.getStatusJunior(),
                curFlow.getMainId(),
                inputParam.getCurUserId(),
                inputParam.getRemark());

        if(curFlow.getType()==Flow.TYPE_CONTRACT ){
            //新建合同
            //最后流程结束，要修改对应主单据的状态
             if(inputParam.getFlowNextStatus().equals(Contract.STATUS_FINISHED)) {
                 Contract contract = new Contract();
                 contract.setId(curFlow.getMainId());
                 contract.setStatus(Contract.STATUS_FINISHED);
                 contractService.updateById(contract);
             }
        }else if(curFlow.getType()==Flow.TYPE_CONTRACT_DEFER){
            //合同延期
            if(inputParam.getFlowNextStatus().equals(Contract.STATUS_CREATE) &&
                    inputParam.getStatusJunior().equals(Contract.STATUS_JUNIOR_RETURN)) {
                //延期初审被驳回，将合同的提醒打开
                Contract contract = new Contract();
                contract.setId(curFlow.getMainId());
                contract.setIsExpireCaution(1);
                contractService.updateById(contract);
            }else if(inputParam.getFlowNextStatus().equals(Contract.STATUS_FINISHED)){
                //修改日期终审通过，最后要更新合同数据
                List<Flow> list = getJsonData(curFlow.getMainId());
                if(list.size()>0 &&list.get(0).getJsonData()!=null &&
                        list.get(0).getJsonData().length()>0){
                    Contract temp = JSON.parseObject(list.get(0).getJsonData(), Contract.class);
                    temp.setIsExpireCaution(1);
                    contractService.updateById(temp);
                }
            }
        }else if(curFlow.getType()==Flow.TYPE_CONTRACT_TEMP){
            //最后流程结束，要修改对应主单据的状态
            if(inputParam.getFlowNextStatus().equals(Contract.STATUS_FINISHED)) {
                Contract currentContract = contractService.getById(curFlow.getMainId());
                //原本就还是临时合同标识，未转正状态，则不动
                if(currentContract.getIsTemp().equals(1)){
                    //此时是临时合同未转正终审通过，将标识改为等转正式
                    Contract contract = new Contract();
                    contract.setId(curFlow.getMainId());
                    contract.setIsTemp(0);
                    contractService.updateById(contract);
                }else{
                    Contract contract = new Contract();
                    contract.setId(curFlow.getMainId());
                    contract.setStatus(Contract.STATUS_FINISHED);
                    contractService.updateById(contract);
                }

            }
        }
        return ResponseInfo.success();
    }
    //获取流程数据里，jsondata不为空的数据
    private List<Flow> getJsonData(String mainId){
        QueryWrapper ew = new QueryWrapper<Flow>();
        ew.eq("main_id", mainId);
        ew.isNotNull("json_data");
        ew.orderByDesc("create_time");
        List<Flow> list = list(ew);
        return list;
    }

    @Override
    public Map flowDisAgree(InputParam inputParam) {
        return null;
    }

    @Override
    public List<Flow> getByParams(InputParam inputParam) {
        QueryWrapper ew = new QueryWrapper<Flow>();
        if(inputParam.getStatus()!=null) {
           ew.eq("status", inputParam.getStatus());
        }
        if(!StringUtils.isEmpty(inputParam.getMainId())) {
            //主单据来源id
            ew.eq("main_id", inputParam.getMainId());
        }
        if(inputParam.getIsFinished()!=null && inputParam.getIsFinished()) {
            //流程结束时间，true，表示流程已结束
            ew.isNotNull("end_time");
        }else{
            //false表示在途单，默认
            ew.isNull("end_time");
        }
        ew.orderByDesc("create_time");
        List<Flow> list = list(ew);
        return list;
    }
}
